package bll

import (
	"context"
	"encoding/json"
	"fmt"
	lock "github.com/felixrobcoding/go-common/redis"
	log "maya-service/collector/logger"
	"maya-service/event"
	"maya-service/model"
	"maya-service/model/po"
	"maya-service/store/redis"
	"maya-service/utils"
	"sync"
	"time"
)

var OrderCacheInstance = NewOrderCache()

type OrderCache struct {
	lock sync.Mutex
}

func NewOrderCache() *OrderCache {

	return &OrderCache{
		lock: sync.Mutex{},
	}
}

func (o *OrderCache) Init() {
	// 订单创建
	event.Subscribe(event.OrderCreated, func(ctx context.Context, e event.Event, payload interface{}) {
		return
	})

	// 订单抢单成功
	event.Subscribe(event.GrabOrderSuccess, func(ctx context.Context, e event.Event, payload interface{}) {
		// 刷新缓存信息
		err := OrderCacheInstance.RefreshOrderCache()
		if err != nil {
			log.Error("OrderCache 刷新缓存信息失败")
			return
		}
		return
	})

	// 刷新缓存
	event.Subscribe(event.RefreshOrderCache, func(ctx context.Context, e event.Event, payload interface{}) {
		// 刷新缓存信息
		err := OrderCacheInstance.RefreshOrderCache()
		if err != nil {
			log.Error("OrderCache 刷新缓存信息失败")
			return
		}
		return
	})

	_ = o.RefreshOrderCache()
	return
}

// RefreshOrderCache 刷新缓存失败
func (o *OrderCache) RefreshOrderCache() (err error) {
	log.Info("################# 刷新缓存 RefreshOrderCache")
	th := lock.TRedLock{}
	bSuccess, err := th.Lock(redis.KV, fmt.Sprintf("RefreshOrderCache:lock"), time.Second*10)
	if err != nil || !bSuccess {
		return err
	}
	defer th.UnLock(redis.KV)

	unix := time.Now().Unix()
	list, _ := Order.List(context.Background(), &model.OrderListRequest{
		CreatedAt: &unix,
		Index:     1,
		Size:      10000,
	})

	if len(list.List) > 0 {
		var newList []*po.OrderDataInfo
		for i, v := range list.List {
			orderData := &po.OrderContext{}
			_ = json.Unmarshal([]byte(v.OrderContext), orderData)
			newList = append(newList, &po.OrderDataInfo{
				OrderInfo: *list.List[i],
				OrderData: orderData,
			})

			utils.GCache.Set(v.OrderId, newList[i], time.Hour*1)
		}

		utils.GCache.Set("order_list", newList, time.Second*300)
	}
	return
}

// GetOrderInfo 获取订单信息
func (o *OrderCache) GetOrderInfo(orderId string) (orderInfo *po.OrderDataInfo, err error) {
	if v, ok := utils.GCache.Get(orderId); ok {
		return v.(*po.OrderDataInfo), nil
	}
	return &po.OrderDataInfo{}, nil
}

// GetOrderList 获取订单列表
func (o *OrderCache) GetOrderList() (list []*po.OrderDataInfo, err error) {
	if v, ok := utils.GCache.Get("order_list"); ok {
		return v.([]*po.OrderDataInfo), nil
	}

	o.lock.Lock()
	defer o.lock.Unlock()

	if v, ok := utils.GCache.Get("order_list"); ok {
		return v.([]*po.OrderDataInfo), nil
	}

	// 刷新缓存
	_ = o.RefreshOrderCache()

	if v, ok := utils.GCache.Get("order_list"); ok {
		return v.([]*po.OrderDataInfo), nil
	}
	return
}
